import type { Dispatch } from "@reduxjs/toolkit"

import { loginApi, logoutApi, noticesApi, permissionApi } from "@/api/user"
import { Toast } from "@/components/messages"
import { MenuItem, Permission } from "@/interface/user/user"
import { encryptUserInfo } from "@/utils/encrypt"

import type { LoginParams } from "../../interface/user/login"
import { createAsyncAction } from "../utils"
import { reset, setPermissions, setUserItem } from "./user.store"
// typed wrapper async thunk function demo, no extra feature, just for powerful typings
export const loginAsync = createAsyncAction<LoginParams, boolean>(payload => {
	return async dispatch => {
		const [err, res] = await loginApi(payload)

		if (err) return false

		localStorage.setItem("t", res.token)
		localStorage.setItem("username", res.userInfo.username || "")
		localStorage.setItem("nickName", res.userInfo.nickName)
		localStorage.setItem("d1", encryptUserInfo(res.userInfo.id))
		localStorage.setItem("u1", encryptUserInfo(res.userInfo))

		await dispatch(
			setUserItem({
				userInfo: res.userInfo,
				nickName: res.userInfo.nickName,
				username: res.userInfo.username || "",
				token: res.token
			})
		)
		// await getPermissionsAsync()

		// dispatch(getPermissionsAsync())
		return true
	}
})

export const logoutAsync = () => async (dispatch: Dispatch) => {
	const [err] = await logoutApi()

	if (err) return false

	localStorage.removeItem("t")

	dispatch(reset())

	return true
}

const permissionsHandler = (permissionData: Permission[]): { menuData: MenuItem[]; permissions: string[] } => {
	const permissions: string[] = []
	// const { top, sec, thi } = avilablePages.reduce(
	// 	(prev, item) => {
	// 		// eslint-disable-next-line @typescript-eslint/no-unused-vars
	// 		const [_, i1, i2, i3] = item.path.split("/")
	// 		i1 && !prev.top.includes(i1) && prev.top.push(i1)
	// 		i2 && !prev.sec.includes(i2) && prev.sec.push(i2)
	// 		i3 && !prev.thi.includes(i3) && prev.thi.push(i3)
	// 		return prev
	// 	},
	// 	{ top: [] as string[], sec: [] as string[], thi: [] as string[] }
	// )
	const reducer = (currentPermissions: Permission[]) =>
		currentPermissions.reduce((prev, item) => {
			item.children?.map(i => permissions.push(i.id))
			// if (top.includes(item.id) || sec.includes(item.id) || thi.includes(item.id)) {
			item.bottom && item.bottom.forEach(button => permissions.push(button.id))
			prev.push({
				id: item.id,
				permissionName: item.permissionName,
				orderNum: item.orderNum,
				children: item.children ? reducer(item.children) : null,
				component: item.component,
				path: item.path,
				icon: item.icon
			} as MenuItem)
			// }
			return prev
		}, [] as MenuItem[])

	const menuData = reducer(permissionData)
	return {
		menuData,
		permissions
	}
}

export const getPermissionsAsync = () => async (dispatch: Dispatch) => {
	try {
		const [err, res] = await permissionApi()
		if (err) return false

		const { menuData, permissions } = permissionsHandler(res)
		dispatch(
			setPermissions({
				menuData,
				permissions
			})
		)
	} catch (error) {
		console.log(error)
		Toast.error("Please inspect your network")
		return false
	}
}

export const updateNotices = () => async (dispatch: Dispatch) => {
	try {
		const [err, res] = await noticesApi()
		if (err) return false
		dispatch(
			setPermissions({
				notices: res as unknown as Record<string, number>
			})
		)
	} catch (error) {
		console.log(error)
		Toast.error("Please inspect your network")
		return false
	}
}
